/*******************************************************************************
* Copyright (c) 2008, Jeferson Jose de Miranda                                 *
* UDESC - Universidade do Estado de Santa Catarina                             *
* All rights reserved.                                                         *
*                                                                              *
* Redistribution and use in source and binary forms, with or without           *
* modification, are permitted provided that the following conditions are met:  *
*     * Redistributions of source code must retain the above copyright         *
*       notice, this list of conditions and the following disclaimer.          *
*     * Redistributions in binary form must reproduce the above copyright      *
*       notice, this list of conditions and the following disclaimer in the    *
*       documentation and/or other materials provided with the distribution.   *
*     * Neither the name of the Universidade do Estado de Santa Catarina nor   *
*       the names of its contributors may be used to endorse or promote        *
*       products derived from this software without specific prior written     *
*       permission.                                                            *
*                                                                              *
* THIS SOFTWARE IS PROVIDED BY JEFERSON JOSE DE MIRANDA "AS IS" AND ANY        *
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED    *
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE       *
* DISCLAIMED. IN NO EVENT SHALL JEFERSON JOSE DE MIRANDA BE LIABLE FOR ANY     *
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES   *
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; *
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND  *
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT   *
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF     *
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.            *
*******************************************************************************/

/**
 * \file Time.hpp
 *
 * \brief Retrieves system time.
 *
 * \author Jeferson Jose de Miranda
 *
 * This class was created only to retrieve system time, witch can be used to
 * calculate the time consumed by a method, or to calculate application frame
 * rate.
 **/

#ifndef TIME_HPP
#define TIME_HPP

#include <sys/time.h>

namespace MoveIn
{
    class Time
    {
        private:
        struct timeval start_tv, end_tv;
        struct timezone start_tz, end_tz;

        public:
        Time();
        ~Time();
        void setStartTime();
        void setEndTime();
        double getTime();
        double getTimeDiffSec();
        double getTimeDiffMili();
    };

////////////////////////////////////////////////////////////////////////////////
// Implementation of class MoveIn::Time                                       //
////////////////////////////////////////////////////////////////////////////////

    Time::Time()
    {
        start_tv.tv_sec = 0;
        end_tv.tv_sec = 0;
    }

    Time::~Time()
    {
    }

    void Time::setStartTime()
    {
        gettimeofday(&start_tv, &start_tz);
    }

    void Time::setEndTime()
    {
        gettimeofday(&end_tv, &end_tz);
    }

    double Time::getTime()
    {
        gettimeofday(&start_tv, &start_tz);
        double milliseconds = 1000.0 *
                              ((double)start_tv.tv_sec +
                               (double)start_tv.tv_usec/1000000.0);
        return milliseconds;
    }

    double Time::getTimeDiffSec()
    {
        if(start_tv.tv_sec == 0 ||
           end_tv.tv_sec == 0)
        {
            return 0.0f;
        }
        else
        {
            double t1 = ((double)start_tv.tv_sec +
                         (double)start_tv.tv_usec/1000000.0);
            double t2 = ((double)end_tv.tv_sec +
                         (double)end_tv.tv_usec/1000000.0);
            return (t2 - t1);
        }
    }

    double Time::getTimeDiffMili()
    {
        return 1000.0 * getTimeDiffSec();
    }

}

#endif
